//
//  QuickPrintController.m
//  This file is part of D&D Manager
//
//Created on 10/7/07 by Matthew Hutton
//
//
//D&D Manager, a D&D Character and battle management program.
//Copyright (C) 2007, Matthew Hutton
//
//This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
//
//This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
//
//You should have received a copy of the GNU General Public License along with this program; if not, write to:
//The Free Software Foundation, Inc.,
//51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

#import "QuickPrintController.h"
#import "limits.h"
#import "AbilityChanged.h"

@implementation QuickPrintController
-(id)init{
	[super init];
	[NSBundle loadNibNamed:@"Quick Print"
					 owner:self];
	sToB=[[[ScoreToBonus alloc] init] autorelease];
	damT=[[[Damage alloc] init] autorelease];
	crit=[[[Critical alloc] init] autorelease];
	wType=[[[WeaponType alloc] init] autorelease];
	[NSValueTransformer setValueTransformer:sToB
									forName:@"ScoreToBonus"];
	[NSValueTransformer setValueTransformer:damT
									forName:@"Damage"];
	[NSValueTransformer setValueTransformer:wType
									forName:@"WeaponType"];
	[NSValueTransformer setValueTransformer:crit
									forName:@"Critical"];
	return self;
}
-(void)awakeFromNib{
	[[quickPrintTV selectedTabViewItem] setView:quickPrintView];
}
-(void)displayWindow{
	[characterController prepareContent];
	[characterController setSortDescriptors:[NSArray arrayWithObject:[[NSSortDescriptor alloc] initWithKey:@"name" ascending:YES]]];
	[quickPrintWindow makeKeyAndOrderFront:self];
}
-(NSManagedObjectContext *)managedObjectContext{
	return [[[NSDocumentController sharedDocumentController] currentDocument] managedObjectContext];
}
//copy pasted.
-(void)setupCharactersSpellsForChar:(NSManagedObject *)obj
					   forOverwrite:(BOOL)overwrite
					startingAtLevel:(int)startLevel{
	if(mObjC==nil){
		mObjC=[[[NSDocumentController sharedDocumentController] currentDocument] managedObjectContext];
	}
	if(model==nil){
		model=[[mObjC persistentStoreCoordinator] managedObjectModel];
	}
	//NSLog(@"starting processing of char spells setup");
	if(charactersSpellClasses==nil){
		charactersSpellClasses=[[NSMutableArray alloc] initWithCapacity:5];
	}else{
		[charactersSpellClasses removeAllObjects];
	}
	int i;
	for(i=0;i<3;i++){
		//NSLog(@"character=%@",[obj valueForKey:@"name"]);
		NSManagedObject *characterClass=[obj valueForKey:[NSString stringWithFormat:@"characterClass%d",i+1]];
		if([[characterClass valueForKey:@"castsSpells"] boolValue]){
			NSArray *spellLevels=[[[[obj valueForKey:@"spellLevel"] allObjects] filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:[NSString stringWithFormat:@"characterClass.name like[c] \"%@\" AND level>=%d",[characterClass valueForKey:@"name"],startLevel]]] sortedArrayUsingDescriptors:[NSArray arrayWithObject:[[NSSortDescriptor alloc] initWithKey:@"level" ascending:YES]]];
			if([[characterClass valueForKey:@"allSpontaneous"] boolValue]){
				NSSet *spellClasses1=[characterClass valueForKey:@"spellClass"];
				NSMutableSet *spellClasses2=[NSMutableSet setWithCapacity:10];
				[spellClasses2 setSet:[obj valueForKey:@"spellClass"]];
				[spellClasses2 intersectSet:spellClasses1];
				NSArray *sc2=[[spellClasses2 allObjects] filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:[NSString stringWithFormat:@"level>=%d",startLevel]]];
				int j;
				NSMutableArray *sct=[NSMutableArray arrayWithCapacity:[sc2 count]];
				for(j=0;j<[sc2 count];j++){
					NSManagedObject *spellClass=[sc2 objectAtIndex:j];
					NSManagedObject *tempSpellClass=[[NSManagedObject alloc] initWithEntity:[[model entitiesByName]  objectForKey:@"TempSpellClass"] insertIntoManagedObjectContext:mObjC];
					[tempSpellClass setValue:spellClass
									  forKey:@"spellClass"];
					[tempSpellClass setValue:obj
									  forKey:@"character"];
					int slEntry=[[spellClass valueForKey:@"level"] intValue]-[[characterClass valueForKey:@"minimumSpellLevel"] intValue];
					int spellsLeft=[[[spellLevels objectAtIndex:slEntry] valueForKey:@"spellsLeft"] intValue];
					[tempSpellClass setValue:[NSNumber numberWithInt:spellsLeft]
									  forKey:@"noOfSpellsLeftTemp"];
					[tempSpellClass setValue:nil
									  forKey:@"castAtLevelTemp"];
					[sct addObject:tempSpellClass];
				}
				[charactersSpellClasses setArray:sct];
				[charactersSpellClasses sortUsingDescriptors:[NSArray arrayWithObjects:[[NSSortDescriptor alloc] initWithKey:@"spellClass.level" ascending:YES],[[NSSortDescriptor alloc] initWithKey:@"spellClass.spell.name" ascending:YES],nil]];
			}else{
				NSMutableSet *spellClasses2=[NSMutableSet setWithCapacity:1];
				//set up set of all the characters spells.
				if([[characterClass valueForKey:@"healOrHarmSpontaneous"] boolValue] || [[characterClass valueForKey:@"summoningSpontaneous"] boolValue]){
					NSSet *spellClasses1=[characterClass valueForKey:@"spellClass"];
					[spellClasses2 setSet:[obj valueForKey:@"spellClass"]];
					[spellClasses2 intersectSet:spellClasses1];
				}
				int j;
				for(j=0;j<[spellLevels count];j++){
					NSManagedObject *spellLevel=[spellLevels objectAtIndex:j];
					//now process.
					NSArray *arrayOfMemSpells=[[[[spellLevel valueForKey:@"memorisedSpell"] allObjects] filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"castable == 1"]] sortedArrayUsingDescriptors:[NSArray arrayWithObject:[[NSSortDescriptor alloc] initWithKey:@"name" ascending:YES]]];
					NSMutableArray *spontSCs=[NSMutableArray arrayWithCapacity:1];
					if(!overwrite){
						//check if there are spells to overwrite.
						int g;
						BOOL noSLsGreater=YES;
						for(g=j;g<[spellLevels count];g++){
							NSManagedObject *superLevel=[spellLevels objectAtIndex:g];
							if([[superLevel valueForKey:@"spellsLeft"] intValue]>0 && [[[[superLevel valueForKey:@"memorisedSpell"] allObjects] filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"castable==1"]] count]>0){
								NSLog(@"a spell left");
								noSLsGreater=NO;
								break;
							}
						}
						//no possible spells to overwrite.
						if(noSLsGreater){
							continue;
						}
						//if we are overwriting spontaneous spells are useless and don't want adding to the list.
						if([[characterClass valueForKey:@"healOrHarmSpontaneous"] boolValue]){
							if([[obj valueForKey:@"turnUndead"] boolValue] || [AbilityChanged isGood:obj]){
								[spontSCs addObjectsFromArray:[[spellClasses2 allObjects] filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:[NSString stringWithFormat:@"spell.type==0 AND level==%d",j]]]];
							}else{
								[spontSCs addObjectsFromArray:[[spellClasses2 allObjects] filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:[NSString stringWithFormat:@"spell.type==1 AND level==%d",j]]]];
							}
						} 
						if([[characterClass valueForKey:@"summoningSpontaneous"] boolValue]){
							[spontSCs addObjectsFromArray:[[spellClasses2 allObjects] filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:[NSString stringWithFormat:@"spell.type==3 AND level==%d",j]]]];
						}
						int k;
						for(k=0;k<[spontSCs count];k++){
							NSManagedObject *spontSpellClass=[spontSCs objectAtIndex:k];
							int noLeft=[[spellLevel valueForKey:@"spellsLeft"] intValue];
							if(![[spellLevel valueForKey:@"castDomainSpellToday"] boolValue] && [[characterClass valueForKey:@"castsDomainSpells"] boolValue]){
								noLeft++;
							}
							NSManagedObject *tempSpellClass=[[NSManagedObject alloc] initWithEntity:[[model entitiesByName]  objectForKey:@"TempSpellClass"] insertIntoManagedObjectContext:mObjC];
							[tempSpellClass setValue:obj
											  forKey:@"character"];
							[tempSpellClass setValue:spontSpellClass
											  forKey:@"spellClass"];
							[tempSpellClass setValue:[NSNumber numberWithInt:noLeft]
											  forKey:@"noOfSpellsLeftTemp"];
							[tempSpellClass setValue:nil
											  forKey:@"castAtLevelTemp"];
							[charactersSpellClasses addObject:tempSpellClass];
						}
					}
					if([arrayOfMemSpells count]==0 || [[spellLevel valueForKey:@"spellsLeft"] intValue]==0){
						//no spells available at this level.
						//NSLog(@"no spells left");
						continue;
					}
					//now process all the other spells.
					NSMutableArray *memSpells=[NSMutableArray arrayWithCapacity:3];
					int k;
					for(k=0;k<[arrayOfMemSpells count];k++){
						NSManagedObject *memSpell=[arrayOfMemSpells objectAtIndex:k];
						NSManagedObject *spellClass=[memSpell valueForKey:@"spellClass"];
						if(spellClass==nil){
							NSLog(@"Error spellClass for Memorised Spell '%@' is nil",[memSpell valueForKey:@"name"]);
							continue;
						}
						if(![spontSCs containsObject:spellClass]){
							//spell not a "spontaneous" spell which is already in the list.
							//check if spell already in the list of memorised spells.
							int l;
							NSManagedObject *tempSpellClass=nil;
							for(l=0;l<[memSpells count];l++){
								if([[[memSpells objectAtIndex:l] valueForKey:@"spellClass"] isEqualTo:spellClass]){
									tempSpellClass=[memSpells objectAtIndex:l];
									break;
								}
							}
							if(tempSpellClass!=nil){
								[tempSpellClass setValue:[NSNumber numberWithInt:[[tempSpellClass valueForKey:@"noOfSpellsLeftTemp"] intValue]+1]
												  forKey:@"noOfSpellsLeftTemp"];
							}else{
								tempSpellClass=[[NSManagedObject alloc] initWithEntity:[[model entitiesByName]  objectForKey:@"TempSpellClass"] insertIntoManagedObjectContext:mObjC];
								[tempSpellClass setValue:obj
												  forKey:@"character"];
								[tempSpellClass setValue:spellClass
												  forKey:@"spellClass"];
								[tempSpellClass setValue:[NSNumber numberWithInt:1]
												  forKey:@"noOfSpellsLeftTemp"];
								[tempSpellClass setValue:[memSpell valueForKey:@"feat"]
												  forKey:@"featsTemp"];
								if([[spellClass valueForKey:@"level"] intValue]!=[[spellLevel valueForKey:@"level"] intValue]){
									[tempSpellClass setValue:[spellLevel valueForKey:@"level"]
													  forKey:@"castAtLevelTemp"];
								}else{
									[tempSpellClass setValue:nil
													  forKey:@"castAtLevelTemp"];
								}
								[memSpells addObject:tempSpellClass];
								[charactersSpellClasses addObject:tempSpellClass];
							}
						}
					}
				}
			}
		}
		if(i==0){
			c1=[charactersSpellClasses count];
			//NSLog(@"c1=%d",c1);
		}else if(i==1){
			c2=[charactersSpellClasses count];
			//NSLog(@"c2=%d",c2);
		}
	}
	[charactersSpellClasses sortUsingDescriptors:[NSArray arrayWithObjects:[[NSSortDescriptor alloc] initWithKey:@"spellClass.level" ascending:YES], [[NSSortDescriptor alloc] initWithKey:@"spellClass.spell.name" ascending:YES], [[NSSortDescriptor alloc] initWithKey:@"spellClass.domainSpell" ascending:YES], nil]];
}
-(IBAction)characterChangedNext:(id)sender{
	int selection=[characterController selectionIndex];
	selection++;
	[characterController setSelectionIndex:selection];
	NSManagedObject *obj=[[characterController selectedObjects] objectAtIndex:0];
	[self setupCharactersSpellsForChar:obj
						  forOverwrite:NO
					   startingAtLevel:INT_MIN];
	[spellsTableView1 reloadData];
}
-(IBAction)characterChangedPrev:(id)sender{
	int selection=[characterController selectionIndex];
	selection--;
	[characterController setSelectionIndex:selection];
	NSManagedObject *obj=[[characterController selectedObjects] objectAtIndex:0];
	[self setupCharactersSpellsForChar:obj
						  forOverwrite:NO
					   startingAtLevel:INT_MIN];
	[spellsTableView1 reloadData];
}
#pragma mark -
#pragma mark Table Actions
#pragma mark
-(int)numberOfRowsInTableView:(NSTableView *)aTableView{
	if([aTableView isEqualTo:spellsTableView1]){
		return [charactersSpellClasses count];
	}
	return 0;
}
-(id)tableView:(NSTableView *)aTableView
objectValueForTableColumn:(NSTableColumn *)aTableColumn
		   row:(int)row{
	if([aTableView isEqualTo:spellsTableView1]){
		NSManagedObject *tempSpellClass=[charactersSpellClasses objectAtIndex:row];
		NSManagedObject *spellClass=[tempSpellClass valueForKey:@"spellClass"];
		NSString *thingToSend;
		if([aTableColumn isEqualTo:[[aTableView tableColumns] objectAtIndex:0]]){
			if([tempSpellClass valueForKey:@"castAtLevelTemp"]==nil){
				thingToSend=[NSString stringWithFormat:@"%d",[[spellClass valueForKey:@"level"] intValue]];
			}else{
				thingToSend=[NSString stringWithFormat:@"%d (%d)",[[spellClass valueForKey:@"level"] intValue],[[tempSpellClass valueForKey:@"castAtLevelTemp"] intValue]];		
			}
		}else if([aTableColumn isEqualTo:[[aTableView tableColumns] objectAtIndex:1]]){
			thingToSend=[[spellClass valueForKey:@"spell"] valueForKey:@"name"];
		}else{
			int noLeft=[[tempSpellClass valueForKey:@"noOfSpellsLeftTemp"] intValue];
			if(noLeft==0){
				thingToSend=@">0";
			}else{
				thingToSend=[NSString stringWithFormat:@"%d",noLeft];
			}
		}
		if([[spellClass valueForKey:@"domainSpell"] boolValue]){
			return [[NSAttributedString alloc] initWithString:thingToSend attributes:[NSDictionary dictionaryWithObject:[NSColor colorWithDeviceRed:0.7 green:0.1 blue:0.0 alpha:1.0] forKey:NSForegroundColorAttributeName]];
		}else{
			return [[NSAttributedString alloc] initWithString:thingToSend attributes:[NSDictionary dictionaryWithObject:[NSColor blackColor] forKey:NSForegroundColorAttributeName]];	
		}		
	}
	return nil;
}
-(void)dealloc{
	if(charactersSpellClasses!=nil)
		[charactersSpellClasses release];
	[super dealloc];
}
@end
